<template>
  <view :class="['cc-navbar', { fixed, 'has-border': border, 'is-blur': showBlur }]" :style="wrapperStyle">
    <view v-if="safeAreaInsetTop" class="cc-navbar__status-bar" :style="statusBarStyle"></view>
    <view class="cc-navbar__content" :style="contentStyle">
      <view class="cc-navbar__left" @click="onLeftClick">
        <slot name="left">
          <view v-if="leftIcon" class="cc-navbar__left-icon" :style="{ color: leftIconColor, width: iconBox, height: iconBox }">
            <!-- #ifndef MP-WEIXIN -->
            <svg v-if="leftIcon === 'arrow-left'" :width="leftIconSize" :height="leftIconSize" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
              <path :stroke="leftIconColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M15 18l-6-6 6-6"/>
            </svg>
            <!-- #endif -->
            <!-- #ifdef MP-WEIXIN -->
            <view v-if="leftIcon === 'arrow-left'" class="cc-arrow-left" :style="leftArrowStyle"></view>
            <!-- #endif -->
          </view>
          <text v-if="leftText" class="cc-navbar__left-text">{{ leftText }}</text>
        </slot>
      </view>
      <view class="cc-navbar__center">
        <slot name="center">
          <text v-if="title" class="cc-navbar__title" :style="titleComputedStyle">{{ title }}</text>
        </slot>
      </view>
      <view class="cc-navbar__right" :style="rightStyle" @click="onRightClick">
        <slot name="right">
          <text v-if="rightText" class="cc-navbar__right-text">{{ rightText }}</text>
          <view v-if="rightIcon" class="cc-navbar__right-icon">
            <svg v-if="rightIcon === 'more'" :width="leftIconSize" :height="leftIconSize" viewBox="0 0 24 24" fill="currentColor">
              <circle cx="5" cy="12" r="2"/><circle cx="12" cy="12" r="2"/><circle cx="19" cy="12" r="2"/>
            </svg>
          </view>
        </slot>
      </view>
    </view>
  </view>
  <view v-if="fixed && placeholder" class="cc-navbar__placeholder" :style="{ height: placeholderHeight + 'px' }">
    <view v-if="safeAreaInsetTop" class="cc-navbar__placeholder-safe"></view>
  </view>
</template>

<script setup>
/**
多功能自定义导航栏 CCNavbar
- 功能描述: 自定义导航条，支持固定吸顶、左/右区域、标题居中、自动返回、毛玻璃滚动效果
- 使用场景: 代替系统导航栏，在需要个性化内容或透明沉浸式页面
- 参数(Props):
  - safeAreaInsetTop(Boolean, default: true): 顶部安全区
  - placeholder(Boolean, default: false): fixed 时生成等高占位
  - fixed(Boolean, default: true): 是否吸顶
  - border(Boolean, default: true): 是否显示底部分割线
  - leftIcon(String): 左侧图标名，内置 'arrow-left'
  - leftText(String): 左侧文字
  - rightText(String): 右侧文字
  - rightIcon(String): 右侧图标名，内置 'more'
  - title(String): 标题
  - bgColor(String, default: 'transparent'): 背景色
  - titleWidth(String|Number, default: '400rpx'): 标题区域最大宽度
  - height(String|Number, default: 44): 导航内容高度(不含状态栏)
  - leftIconSize(String|Number, default: 20): 左图标大小(px)
  - leftIconColor(String, default: '#303133'): 左图标颜色
  - autoBack(Boolean, default: false): 点击左侧是否自动返回
  - titleStyle(String|Object): 标题样式
  - adaptCapsule(Boolean, default: true): 小程序下自动避开右侧胶囊区
- 事件(Emits):
  - leftClick(): 点击左侧区域
  - rightClick(): 点击右侧区域
- 示例:
  <CCNavbar fixed placeholder title="标题" leftIcon="arrow-left" :autoBack="true" />
*/
import { computed, ref, onMounted } from 'vue'
import { onPageScroll } from '@dcloudio/uni-app'

const props = defineProps({
  safeAreaInsetTop: { type: Boolean, default: true },
  placeholder: { type: Boolean, default: false },
  fixed: { type: Boolean, default: true },
  border: { type: Boolean, default: true },
  leftIcon: { type: String, default: '' },
  leftText: { type: String, default: '' },
  rightText: { type: String, default: '' },
  rightIcon: { type: String, default: '' },
  title: { type: String, default: '' },
  bgColor: { type: String, default: 'transparent' },
  titleWidth: { type: [String, Number], default: '400rpx' },
  // 新增：标题颜色与字号
  titleColor: { type: String, default: '#303133' },
  titleSize: { type: [String, Number], default: 16 },
  height: { type: [String, Number], default: 44 },
  leftIconSize: { type: [String, Number], default: 8 },
  leftIconColor: { type: String, default: '#303133' },
  autoBack: { type: Boolean, default: false },
  titleStyle: { type: [String, Object], default: '' },
  adaptCapsule: { type: Boolean, default: true },
  // 新增：是否使用页面滚动判断毛玻璃（某些小程序不支持在组件内接收 onPageScroll）
  usePageScroll: { type: Boolean, default: true },
  // 新增：外部强制控制毛玻璃开关
  blurForce: { type: Boolean, default: false },
})

const emit = defineEmits(['leftClick', 'rightClick'])

const sysInfo = uni.getSystemInfoSync()
const statusBarHeight = ref(sysInfo.statusBarHeight || 0)

const iconBox = computed(() => (Number(props.leftIconSize) + 8) + 'px')

const contentHeightPx = computed(() => {
  const h = typeof props.height === 'number' ? props.height : parseInt(String(props.height))
  return isNaN(h) ? 44 : h
})

const totalNavHeight = computed(() => (props.safeAreaInsetTop ? statusBarHeight.value : 0) + contentHeightPx.value)

const placeholderHeight = computed(() => totalNavHeight.value)

const titleStyleObj = computed(() => props.titleStyle)
const titleMaxWidth = computed(() => typeof props.titleWidth === 'number' ? props.titleWidth + 'rpx' : String(props.titleWidth))
// 汇总标题样式，支持外部更直观地传入颜色与字号
const titleComputedStyle = computed(() => {
  const styleArr = []
  styleArr.push({ maxWidth: titleMaxWidth.value })
  if (props.titleColor) styleArr.push({ color: props.titleColor })
  if (props.titleSize !== undefined && props.titleSize !== null) {
    const sz = typeof props.titleSize === 'number' ? props.titleSize + 'px' : String(props.titleSize)
    styleArr.push({ fontSize: sz })
  }
  if (props.titleStyle) styleArr.push(props.titleStyle)
  return styleArr
})
const rightPaddingPx = ref(12)
onMounted(() => {
  // 避让小程序胶囊按钮区域（主要是微信）
  if (!props.adaptCapsule) return
  try {
    const rect = typeof uni.getMenuButtonBoundingClientRect === 'function' ? uni.getMenuButtonBoundingClientRect() : null
    if (rect && rect.left && sysInfo.windowWidth) {
      const avoid = Math.max(12, sysInfo.windowWidth - rect.left)
      rightPaddingPx.value = avoid + 6 // 略加 6px 缓冲
    }
  } catch (e) {
    // ignore
  }
})

const wrapperStyle = computed(() => ({
  backgroundColor: props.bgColor,
}))

const contentStyle = computed(() => {
  const style = { height: contentHeightPx.value + 'px' }
  if (props.adaptCapsule) {
    // 右侧动态内边距：基础 12px + 胶囊避让宽度
    style.paddingRight = (12 + rightPaddingPx.value) + 'px'
  }
  return style
})

// 仅作用于右侧区域，避免影响居中对齐
const rightStyle = computed(() => ({
  paddingRight: rightPaddingPx.value + 'px',
}))

// 小程序下组件内部不一定能拿到 onPageScroll，这里提供两种方式：
// 1) usePageScroll 开启：组件内部感知滚动
// 2) 关闭 usePageScroll，由外部通过 blurForce 受控
const internalScrollBlur = ref(false)
onPageScroll((e) => {
  if (props.fixed && props.usePageScroll) {
    internalScrollBlur.value = e.scrollTop > 0
  }
})
const showBlur = computed(() => props.blurForce || (props.usePageScroll && internalScrollBlur.value))

function onLeftClick() {
  emit('leftClick')
  if (props.autoBack) {
    const pages = getCurrentPages && getCurrentPages()
    if (pages && pages.length > 1) {
      uni.navigateBack({ delta: 1 })
    } else {
      // H5 首屏无历史时不处理
    }
  }
}
function onRightClick() {
  emit('rightClick')
}

const statusBarStyle = computed(() => ({
  height: (props.safeAreaInsetTop ? statusBarHeight.value : 0) + 'px',
}))
// 新增：微信小程序左箭头（通过边框绘制），根据 leftIconSize 与 leftIconColor 计算样式
const leftArrowStyle = computed(() => {
  const sizeNum = typeof props.leftIconSize === 'number' ? props.leftIconSize : parseInt(String(props.leftIconSize))
  const size = isNaN(sizeNum) ? 20 : sizeNum
  const line = Math.max(2, Math.round(size / 6)) // 线宽
  return {
    width: size + 'px',
    height: size + 'px',
    display: 'inline-block',
    borderRight: `${line}px solid ${props.leftIconColor}`,
    borderBottom: `${line}px solid ${props.leftIconColor}`,
    transform: 'rotate(135deg)',
    boxSizing: 'content-box',
  }
})
</script>

<style scoped>
.cc-navbar {
  width: 100%;
  left: 0;
  top: 0;
  z-index: 998;
}
.cc-navbar.fixed {
  position: fixed;
}
.cc-navbar.has-border .cc-navbar__content {
  border-bottom: 1px solid rgba(0,0,0,0.06);
}
/* 默认毛玻璃效果（H5、App 等支持 backdrop-filter 的平台） */
.cc-navbar.is-blur {
  background-color: rgba(255,255,255,0.6);
  backdrop-filter: saturate(180%) blur(10px);
  -webkit-backdrop-filter: saturate(180%) blur(10px);
  box-shadow: 0 2px 6px rgba(0,0,0,0.06);
}
/* #ifdef MP-WEIXIN */
/* 微信小程序降级处理：不支持 backdrop-filter 时使用更实的半透明与阴影 */
.cc-navbar.is-blur {
  background-color: rgba(255,255,255,0.92);
  box-shadow: 0 2px 6px rgba(0,0,0,0.08);
}
/* #endif */

.cc-navbar__status-bar {
  width: 100%;
  /* 兼容 H5 刘海安全区 */
  padding-top: constant(safe-area-inset-top);
  padding-top: env(safe-area-inset-top);
}
.cc-navbar__content {
  position: relative; /* 供居中元素绝对定位 */
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-left: 12px;
  padding-right: 12px; /* 基础内边距，不包含胶囊避让 */
  box-sizing: border-box;
  background-color: transparent;
}
.cc-navbar__left,
.cc-navbar__right {
  min-width: 120rpx;
  display: flex;
  align-items: center;
  height: 100%;
}
/* 绝对居中，不受左右宽度影响 */
.cc-navbar__center {
  position: absolute;
  left: 50%;
  top: 0;
  transform: translateX(-50%);
  height: 100%;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: auto;
}
.cc-navbar__title {
  font-size: 16px;
  color: #303133;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cc-navbar__left-text,
.cc-navbar__right-text {
  font-size: 14px;
  color: #303133;
}
.cc-navbar__left-icon,
.cc-navbar__right-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 6px;
}
.cc-navbar__placeholder-safe {
  padding-top: constant(safe-area-inset-top);
  padding-top: env(safe-area-inset-top);
}
.cc-arrow-left {
  display: inline-block;
  vertical-align: middle;
}
</style>